﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Collections;
using System.Data;
using System.Data.Common;

namespace DataBaseConnection
{    
    public abstract class PConnOrder
    {
        public PConnOrder()
        { 
        
        }

        /// <summary>
        /// 设置连接字符串
        /// </summary>
        /// <param name="_ConnectionString">连接字符串</param>
        public PConnOrder(string _ConnectionString)
        {
            ConnectionString = _ConnectionString;
        }

        #region 变量
        /// <summary>
        /// 数据库连接字符串
        /// </summary>
        protected string ConnectionString = string.Empty;
        /// <summary>
        /// 事务开始时生成的关键索引
        /// </summary>
        protected string TransactionKey = string.Empty;
        /// <summary>
        /// 连接对象
        /// </summary>
        protected DbConnection conn = null;
        /// <summary>
        /// 操作对象
        /// </summary>
        protected DbCommand cmd = null;
        /// <summary>
        /// 事务
        /// </summary>
        protected DbTransaction myTrans = null;
        #endregion        

        #region 需重写的方法
        /// <summary>
        /// 当前数据库类型
        /// </summary>
        public abstract DataBaseType CurrentBaseType
        {
            get;
        }
        /// <summary>
        /// 返回单个字段值
        /// </summary>
        /// <param name="porName">Sql语句或[存储过程] 名称</param>
        /// <param name="cmdText">参数集合([存储过程参数名],[值])</param>		
        /// <returns>返回第一行第一列的值，不管是什么数据类型，先封装成 Object</returns>
        public abstract object ExecuteScalar(string porName, IDataParameter[] cmdParms, CommandType ct);
        /// <summary>
        /// 快速访问只读数据集流
        /// </summary>
        /// <param name="porName">Sql语句或[存储过程] 名称</param>
        /// <param name="cmdParms">参数集合([存储过程参数名],[值])</param>
        /// <returns>返回通过数据源执行命令的只进结果集流</returns>
        public abstract IDataReader ExecuteReader(string porName, IDataParameter[] cmdParms, CommandType ct);
        /// <summary>
        /// 返回数据表集合
        /// </summary>
        /// <param name="porName">Sql语句或[存储过程] 名称</param>
        /// <param name="cmdParms">参数集合([存储过程参数名],[值])</param>
        /// <returns>返回结果集的封装对象</returns>
        public abstract DataSet ExecuteDataSet(string porName, IDataParameter[] cmdParms, CommandType ct);
        /// <summary>
        /// 执行 [添加],[更新]和[删除] 命令,返回受影响的行
        /// </summary>		
        public abstract int ExecuteNonQuery(string porName, IDataParameter[] cmdParms, CommandType ct);
        /// <summary>
        /// 事务开始
        /// </summary>
        public abstract void TransactionStart();
        /// <summary>
        /// 事务结束
        /// </summary>
        public abstract void TransactionEnd();

        /// <summary>
        /// 打开连接
        /// </summary>
        public virtual void ConnectionOpen()
        {
            //判断连接的状态。如果是关闭状态，则打开
            if (conn != null && conn.State != ConnectionState.Open)
            {
                conn.ConnectionString = ConnectionString;
                conn.Open();
            }
        }

        /// <summary>
        /// 集中处理连接属性
        /// </summary>
        /// <param name="cmdText">Sql语句或[存储过程] 名称</param>
        /// <param name="cmdParms">参数集合([存储过程参数名],[值])</param>
        /// <param name="ct">命令类型</param>
        protected virtual void PrepareCommand(string cmdText, IDataParameter[] cmdParms, CommandType ct)
        {            
            //判断连接的状态。如果是关闭状态，则打开
            ConnectionOpen();
            
            //cmd属性赋值
            cmd.Connection = conn;
            cmd.CommandText = cmdText;
            cmd.CommandType = ct;
            cmd.Parameters.Clear();

            //添加cmd需要的存储过程参数
            if (cmdParms != null)
            {
                foreach (IDataParameter parm in cmdParms)
                {
                    if (parm != null)
                    {
                        cmd.Parameters.Add(parm);
                    }
                }
            }
        }
        /// <summary>
        /// 返回该表内所有字段的数据类型及长度
        /// </summary>	
        public DataTable GetSchema(string collectionName, string[] restrictionValues)
        {
            //对象处理
            PrepareCommand(string.Empty, null, CommandType.Text);

            try
            {
                return conn.GetSchema(collectionName, restrictionValues);
            }
            catch (System.Exception)
            {
                throw;
            }
            finally
            {
                ConnectionClose();
            }
        }
        /// <summary>
        /// 关闭连接
        /// </summary>
        public virtual void ConnectionClose()
        {
            if (conn != null || conn.State != ConnectionState.Closed)
            {
                conn.Close();
            }
        }
        /// <summary>
        /// 返回新参数对象
        /// </summary>        
        public abstract IDataParameter GetNewParameter(string parameterName, Object Value);
        public abstract IDataParameter GetNewParameter(string parameterName, Object Value, ParameterDirection OutType);

        /// <summary>
        /// 返回参数返回值
        /// </summary>
        /// <param name="parameterName">参数名称</param>
        /// <returns></returns>
        public object GetParameterOfOutPut(string parameterName)
        {
            return cmd.Parameters[parameterName].Value;
        }
        
        /// <summary>
        /// 查询分页
        /// </summary>
        /// <param name="sqlText">查询语句</param>        
        /// <param name="Primary">主键</param>
        /// <param name="Orderby">排序</param>
        /// <param name="MaxRows">每页行数</param>
        /// <param name="CurrPage">当前页数</param>
        /// <returns>Tables[0]:查询数据 Tables[1].Rows[0][0]:总数据量</returns>
        public abstract DataSet SplitPage(string sqlText, string Primary, string Orderby, int MaxRows, int CurrPage);

        #endregion

        #region 公共方法
        /// <summary>
        /// 设置连接字符串
        /// </summary>
        public string SetConnectionText
        {
            set { ConnectionString = value; }
            get { return ConnectionString; }
        }        
        #endregion
    }
}
